package com.ly.mpayment.persist.service.upshoppro;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.ly.mpayment.core.util.*;
import com.ly.mpayment.persist.entity.*;
import com.ly.mpayment.persist.service.matchingstrategy.IMatchingStrategyService;
import com.ly.mpayment.persist.service.uporder.IUporderService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ly.mpayment.persist.hibernate.Page;
import com.ly.mpayment.persist.service.AbstractService;
import com.ly.mpayment.persist.service.upproductlog.IUpProductLogService;

@Service
public class UpShopProServiceImpl extends AbstractService<UpShopProduct, Serializable> implements IUpShopProService{

	@Autowired
	IUpProductLogService logService;

	@Autowired
	IMatchingStrategyService iMatchingStrategyService;


	@Autowired
	IUporderService uporderService;

	@Override
	public boolean addUpshoppro(UpShopProduct shop,User userAdmin) {
		if(shop != null){
			this.saveOrUpdate(shop);
			UpProductLog log = null;
			log = new UpProductLog();
			log.setOperationtarget(Config.product[0]);
			log.setUpShopPro(shop);
			if(userAdmin != null){
				log.setUserLog(userAdmin);
			}
			logService.addUpproductlog(log);
			return true;
		}
		return false;
	}

	@Override
	public boolean updateUpshoppro(UpShopProduct shop,User userAdmin,boolean enable) {
		if(shop != null){
			this.saveOrUpdate(shop);
			UpProductLog log = new UpProductLog();
			log.setOperationtarget(Config.product[1]);
			log.setUpShopPro(shop);
			if(enable){
				log.setRemark("修改产品状态:"+ (shop.getStatus().equals("1") ?"启用" : "禁用"));
			}else{
				log.setRemark(shop.getDiscount().toString());
			}
			if(userAdmin != null){
				log.setUserLog(userAdmin);
			}
			logService.addUpproductlog(log);
			return true;
		}
		return false;
	}

	@Override
	public UpShopProduct findById(String id) {
		return this.findUnique("select u from UpShopProduct u left join fetch u.provincialInformation left join fetch u.operators left join fetch u.businessType left join fetch u.user  where u.status != 0 and u.upprouuid = ?", id);
	}

	@Override
	public Page<UpShopProduct> findPageUpshoppro(Map<String, Object> parameters, int start, int pageSize) {
		return this.findPageByNamed(getPageSql(parameters), parameters, start, pageSize);
	}


	private String getPageSql(Map<String, Object> parameters){
		String sql = "select u from UpShopProduct u left join fetch u.provincialInformation pr left join fetch u.operators op left join fetch u.businessType bs"
				+ " left join fetch u.user us  where u.status != 0 #[and pr.provinceuuid = :provinceuuid ]# #[and op.operatoruid = :operatoruid ]# "
				+ " #[and bs.busuuid = :busuuid ]#  #[and us.useruuid = :useruuid ]# #[and u.productCode = :productCode ]# #[and u.price = :price ]# #[and u.status = :status ]# "
				+ " #[and u.fastchargetype = :fastchargetype ]# #[and u.validity = :validity ]# #[and u.cityName = :cityName ]# ";
		if(parameters.containsKey(":upfacevalue")){
			sql += "and u.upfacevalue in ("+parameters.get(":upfacevalue")+") ";
			parameters.remove(":upfacevalue");
		}
		sql += " order by us.useruuid,upprouuid desc ";
		return sql;
	}
	@Override
	public List<UpShopProduct> findListProduct(String uuids) {
		return this.find("select u from UpShopProduct u where u.upprouuid in ("+uuids+")");
	}

	@Override
	public List<UpShopProduct> findOrderMatch(String operators, String province, String busCode,
			BigDecimal rechargeamount,String facevalue,String cityName) {
		return this.find("select u from UpShopProduct u left join fetch u.user left join fetch u.operators left join" +
				" fetch u.provincialInformation left join fetch u.businessType where u.status = 1 and u.user.userstatus = 1 and u.operators.operatoruid = ?" +
				" and (u.provincialInformation.provincename = ? or u.provincialInformation.provinceuuid = '"+CookieRedis.get("globalCountry")+"')" +
				"  and u.businessType.busCode = ? and u.price * u.discount <= ? and u.upfacevalue = ? " +
						(StringUtils.isBlank(cityName) ? "" : " and u.cityName = '"+cityName.trim()+"' ") +
				" order by u.price * u.discount ", operators,province,busCode,rechargeamount,facevalue);
	}

	/**
	 * 手动匹配不计算折扣
	 * @param operators
	 * @param province
	 * @param busCode
	 * @param discountAmount
	 * @param downfacevalue
	 * @param cityName
	 * @param useruuid
	 * @return
	 */
	@Override
	public List<UpShopProduct> findOrderMatchManual(String operators, String province, String busCode, BigDecimal discountAmount,
													String downfacevalue, String cityName, String useruuid) {
		return this.find("select u from UpShopProduct u left join fetch u.user left join fetch u.operators left join" +
				" fetch u.provincialInformation left join fetch u.businessType where u.status = 1 and u.user.userstatus = 1 and u.user.useruuid = ? and u.operators.operatoruid = ?" +
				// 取消手动匹配全国
				" and ( u.provincialInformation.provincename = ? or u.provincialInformation.provinceuuid = '"+CookieRedis.get("globalCountry")+"') " +
				" and u.businessType.busCode = ? and u.upfacevalue = ? " +
				(StringUtils.isBlank(cityName) ? "" : " and u.cityName = '"+cityName.trim()+"' ") +
				" order by u.price * u.discount ", useruuid,operators,province,busCode,downfacevalue);
	}

	/**
	 * 重复提交查询不包含上N此提交的产品价格最低排序
	 * @param operators
	 * @param province
	 * @param busCode
	 * @param rechargeamount
	 * @param facevalue
	 * @param cityName
	 * @param lastProduct
	 * @return
	 */
	@Override
	public List<UpShopProduct> findOrderMatchRepeat(String operators, String province, String busCode, BigDecimal rechargeamount,
													String facevalue, String cityName, List<String> lastProduct) {
		String hql = "select u from UpShopProduct u left join fetch u.user left join fetch u.operators left join" +
				" fetch u.provincialInformation left join fetch u.businessType where u.status = 1 and u.user.userstatus = 1 and u.operators.operatoruid = ?" +
				" and (u.provincialInformation.provincename = ? or u.provincialInformation.provinceuuid = '"+CookieRedis.get("globalCountry")+"')" +
				"  and u.businessType.busCode = ? and u.price * u.discount <= ? and u.upfacevalue = ? " +
				(StringUtils.isBlank(cityName) ? "" : " and u.cityName = '"+cityName.trim()+"' ") ;
		if(lastProduct != null && !lastProduct.isEmpty()){
			String upprouuids = "";
			for(int i = 0 ; i < lastProduct.size() ; i++){
				upprouuids += "'"+lastProduct.get(i).toString()+"',";
			}
			if(!upprouuids.equals("")){
				upprouuids = upprouuids.substring(0,upprouuids.lastIndexOf(","));
				hql += " and u.upprouuid not in ("+upprouuids+")";
			}
		}
		hql += " order by u.price * u.discount ";
		return this.find(hql, operators,province,busCode,rechargeamount,facevalue);
	}


	@Override
	public List<UpShopProduct> findOrderMatchIn(String operators, String province, String busCode, BigDecimal rechargeamount, String facevalue, String cityName, List<String> lastProduct) {
		String hql = "select u from UpShopProduct u left join fetch u.user left join fetch u.operators left join" +
				" fetch u.provincialInformation left join fetch u.businessType where u.status = 1 and u.operators.operatoruid = ?" +
				" and (u.provincialInformation.provincename = ? or u.provincialInformation.provinceuuid = '"+CookieRedis.get("globalCountry")+"')" +
				"  and u.businessType.busCode = ? and u.price * u.discount <= ? and u.upfacevalue = ? " +
				(StringUtils.isBlank(cityName) ? "" : " and u.cityName = '"+cityName.trim()+"' ") ;
		if(lastProduct != null && !lastProduct.isEmpty()){
			String upprouuids = "";
			for(int i = 0 ; i < lastProduct.size() ; i++){
				upprouuids += "'"+lastProduct.get(i).toString()+"',";
			}
			if(!upprouuids.equals("")){
				upprouuids = upprouuids.substring(0,upprouuids.lastIndexOf(","));
				hql += " and u.upprouuid in ("+upprouuids+")";
			}
		}
		hql += " order by u.price * u.discount ";
		return this.find(hql, operators,province,busCode,rechargeamount,facevalue);
	}

	@Override
	public Page<UpShopProduct> downProductMatchFind(Map<String, Object> parameters, int start, int pageSize) {
		String hql = "select u from UpShopProduct u left join fetch u.provincialInformation left join fetch u.operators left join fetch u.businessType"
				+ " left join fetch u.user  where u.status != 0 #[and u.provincialInformation.provinceuuid =:provinceuuid ]# #[and u.operators.operatoruid = :operatoruid ]# "
				+ " #[and u.businessType.busuuid = :busuuid ]#  ";
		if(parameters.containsKey(":useruuids")){
			String shops []  =   parameters.get(":useruuids").toString().replace("[", "").replace("]", "").split(",");
			parameters.remove(":useruuids");
			String temp = "";
			for (int i = 0; i < shops.length; i++) {
				if(!shops[i].toString().isEmpty()){
					temp += "'"+shops[i].toString().concat("',");
				}
			}
			hql += temp.isEmpty() ? "" : "  and u.user.useruuid in( "+temp.substring(0, temp.lastIndexOf(","))+")  ";
		}

		if(parameters.containsKey(":upfacevalue")){
			String shops []  =   parameters.get(":upfacevalue").toString().replace("[", "").replace("]", "").replaceAll("\"","").split(",");
			parameters.remove(":upfacevalue");
			String temp = "";
			for (int i = 0; i < shops.length; i++) {
				if(!shops[i].toString().isEmpty()){
					temp += "'"+shops[i].toString().concat("',");
				}
			}
			hql += temp.isEmpty() ? "" : "  and u.upfacevalue in( "+temp.substring(0, temp.lastIndexOf(","))+")  ";
		}

		hql += " order by u.productCode,u.createtime desc ";
		Page<UpShopProduct> productPage = this.findPageByNamed(hql.replace("\"", "'"), parameters, start, pageSize);
		return productPage;
	}

	@Override
	public UpShopProduct findProductExits(String provinceuuid, String operatoruid,String busuuid,String useruuid,String upfacevalue,BigDecimal price,String productCode){
		return this.findUnique("select u from UpShopProduct u left join fetch u.provincialInformation p left join fetch u.operators op left join fetch u.businessType bu where "
				+ "  p.provinceuuid = ? and op.operatoruid = ? and bu.busuuid = ?  and u.user.useruuid = ? and u.upfacevalue = ? and u.price = ? and u.productCode = ? ", provinceuuid, operatoruid,busuuid,useruuid,upfacevalue,price,productCode);
	}

	@Override
	public List<UpShopProduct> getProductList(String useruuid) {
		return this.find("select u from UpShopProduct u where u.user.useruuid = ?", useruuid);
	}

	@Override
	public List<UpShopProduct> exportUpProduct(Map<String, Object> parameters) {
		return this.findByNamed(getPageSql(parameters), parameters);
	}

	@Override
	public List<UpShopProduct> findBatchUpProduct(String provinceuuid, String operatoruid, String busuuid,
			String useruuid,String cityName) {
		return this.find("select u from UpShopProduct u left join fetch u.provincialInformation p left join fetch u.operators op left join fetch u.businessType bu where "
				+ "  p.provinceuuid = ? and op.operatoruid = ? and bu.busuuid = ?  and u.user.useruuid = ? and u.status = 1" +
				(StringUtils.isBlank(cityName) ? "" : " and u.cityName = '"+cityName+"'"), provinceuuid, operatoruid,busuuid,useruuid);
	}

	@Override
	public String updateArtificial(JSONObject json) {
		UpShopProduct shopProduct = this.findById(json.getString("upprouuid"));
		if(shopProduct == null){
			return ResultMessage.getFailt("产品不存在");
		}
		shopProduct.setArtificial(json.getBoolean("artificial"));
		if(this.updateEntity(shopProduct) != null){
			return ResultMessage.getSucceed(null);
		}
		return ResultMessage.getFailt("");
	}

	@Override
	public String updatePressOrder(JSONObject json) {
		UpShopProduct shopProduct = this.findById(json.getString("upprouuid"));
		if(shopProduct == null){
			return ResultMessage.getFailt("产品不存在");
		}
		shopProduct.setPressOrder(json.getBoolean("pressOrder"));
		if(this.updateEntity(shopProduct) != null){
			return ResultMessage.getSucceed(null);
		}
		return ResultMessage.getFailt("");
	}

	@Override
	public List<UpShopProduct> findNewProduct(String useruuid, String operators, String provinceuuid, String upfacevalue, String cityName,String bussuuid) {
		// 如果产品的身份是全国，则不加入条件查询
		String sql = "select u from UpShopProduct u left join fetch u.provincialInformation p left join fetch u.operators op " +
				" left join fetch u.businessType bu where  u.user.useruuid = ? and op.operatoruid = ? "
				+ " and (p.provinceuuid = ? or p.provinceuuid = '"+CookieRedis.get("globalCountry")+"' ) and bu.busuuid = ?  and u.status = 1 and u.upfacevalue = ? " +
				(StringUtils.isBlank(cityName) ? "" : " and u.cityName = '"+cityName+"'");

		return this.find( sql + " order by u.discount ", useruuid, operators,provinceuuid,bussuuid,upfacevalue);
	}

	@Override
	public UpShopProduct findByUpShopProduct(String upuuid, String provinceuuid, String operatoruid, String busuuid, String downfacevalue,String cityName) {
		return this.findUnique("select u from UpShopProduct u left join fetch u.provincialInformation p left join fetch u.operators op left join fetch" +
				" u.businessType bu where "
				+ "  p.provinceuuid = ? and op.operatoruid = ? and bu.busuuid = ?  and u.user.useruuid = ? and u.upfacevalue = ? ", provinceuuid, operatoruid,busuuid,upuuid,downfacevalue);
	}

	@Override
	public UpShopProduct findProductAndFaceValue(String upprouuid, String downfacevalue) {
		return this.findUnique("select u from UpShopProduct u left join fetch u.provincialInformation left join fetch u.operators left " +
				" join fetch u.businessType left join fetch u.user  where u.status != 0 and u.upprouuid = ?  ", upprouuid);
	}

	@Override
	public String findPageProductDown(JSONObject json, int start, int pageSize) {
		Page pa = new Page();
		pa.setStart(start);
		pa.setPageSize(pageSize);
		Page page = PaginationUtil.queryPaginationSQL( "select * from ("+ getfindPageProductDownSql(json)+") dfs", pa,
				this.getSession());
		List lists = page.getResult();
		if (lists != null && !lists.isEmpty()) {
			JSONArray array = JsonUtils.getJSONARRAY();
			for (int i = 0; i < lists.size(); i++) {
				JSONObject obj = JsonUtils.getJSONOBJCT();
				Object[] object = (Object[]) lists.get(i);
				obj.put("username", object[0] == null ? "" : object[0].toString());
				obj.put("downname", object[1] == null ? "" : object[1].toString());
				obj.put("provincename", object[2] == null ? "" : object[2].toString());
				obj.put("operatorname", object[3] == null ? "" : object[3].toString());
				obj.put("busname", object[4] == null ? "" : object[4].toString());
				array.add(obj);
			}
			page.setResult(array);
			return JsonUtils.convertObjectToJson(page);
		}
		return JsonUtils.getJSONARRAY().toString();
	}

	public String getfindPageProductDownSql(JSONObject json){
		String sql = " SELECT DISTINCT  u.username,us.username as downname,p.provincename,o.operatorname,b.busname from matchingstrategy m " +
				" inner JOIN user u on u.useruuid = m.upuuid" +
				" inner join user us on us.useruuid = m.downuuid" +
				" inner join provincialinformation p on p.provinceuuid = m.provinceuuid" +
				" inner join operators o on o.operatoruid = m.operatoruid" +
				" inner join businesstype b on b.busuuid = m.busuuid" +
				" where    1 = 1 " ;
		if(json.containsKey("provinceuuid") && !StringUtils.isBlank(json.getString("provinceuuid"))){
			sql += " and o.operatorname = '"+json.getString("provinceuuid")+"' ";
		}
		if(json.containsKey("operatoruid") && !StringUtils.isBlank(json.getString("operatoruid"))){
			sql += " and m.operatoruid  = '"+json.getString("operatoruid")+"' ";
		}
		if(json.containsKey("busuuid") && !StringUtils.isBlank(json.getString("busuuid"))){
			sql += " and m.busuuid = '"+json.getString("busuuid")+"' ";
		}

		if(json.containsKey("useruuid") && !StringUtils.isBlank(json.getString("useruuid")) ){
			JSONArray array = JSONArray.fromObject(json.get("useruuid"));
			if(array.size() > 0){
				List<String> list = new ArrayList<>();
				for(int i = 0 ; i < array.size();i++){
					list.add("'"+array.getString(i)+"'");
				}
				sql += " and m.downuuid in ("+ org.apache.commons.lang.StringUtils.join(list.toArray(),",")+") ";
			}
		}
		if(json.containsKey("upuseruuid") && !StringUtils.isBlank(json.getString("upuseruuid"))){
			JSONArray array = JSONArray.fromObject(json.get("upuseruuid"));
			if(array.size() > 0){
				List<String> list = new ArrayList<>();
				for(int i = 0 ; i < array.size();i++){
					list.add("'"+array.getString(i)+"'");
				}
				sql += " and m.upuuid in ("+org.apache.commons.lang.StringUtils.join(list.toArray(),",")+") ";
			}
		}
		sql += " order by u.username,us.username ";
		return sql;
	}


	@Override
	public String deleteDownProduct(String data) {
		JSONArray array = JSONArray.fromObject(data);
		for(int i = 0 ; i < array.size() ; i++){
			UpShopProduct product = this.findById(array.getJSONObject(i).getString("upprouuid"));
			if(product == null){
				return ResultMessage.getFailt("产品不存在");
			}
			//检查产品是否存在匹配
			if(iMatchingStrategyService.findByCount(product.getUpprouuid())){
				return ResultMessage.getFailt("产品存在匹配,禁止删除");
			}
			//查询产品是否存在订单
			int count = this.uporderService.findbyProduct(product.getUpprouuid());
			if(count > 0){
				return ResultMessage.getFailt("产品被使用,禁止删除");
			}
			logService.deleteLog(product);
			this.getSession().createSQLQuery(" delete from upshopproduct where upprouuid = '"+product.getUpprouuid()+"'").executeUpdate();
		}
		return ResultMessage.getSucceed();
	}

	@Override
	public void updateProductPriceUp(ProductPriceUp price) {
		UpShopProduct product = this.findById(price.getProductId().getUpprouuid());
		product.setDiscount(price.getAfterDiscount());
		product.setDiscountAmount(product.getPrice().multiply(price.getAfterDiscount()));
		logger.info("updateProductPrice:"+product.getUpprouuid()+","+price.getAfterDiscount()+","+product.getDiscountAmount());
		this.updateEntity(product);
	}
}
